'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-09-25 09:48:29
@LastEditTime: 2019-11-19 11:16:47
@LastEditors: Please set LastEditors
'''

from ...service.mongo_bill_service import MongoBillFilter
from ...pao_python.pao.commom import get_data
from ...service.common import insert_data, find_data, update_data, delete_data, get_condition, get_info
from ...pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.buss_pub.bill_manage import BillManageService, OperationType, TypeId, Status
from ...pao_python.pao.service.security.security_utility import get_current_account_id
from ...pao_python.pao.service.security.security_service import RoleService
import hashlib
import re
import datetime
import uuid
import pandas as pd
from ...pao_python.pao.data import process_db, dataframe_to_list, DataProcess, DataList, get_cur_time, get_first_last_day_month, get_string_to_date
from ...service.app.my_order import OrderStatus
'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-07-25 15:14:25
@LastEditTime: 2019-07-25 15:14:25
@LastEditors: your name
'''
# -*- coding: utf-8 -*-

'''
住宿区域类型函数
'''


class hotelZoneTypeService(MongoService):
    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        DataProcess.__init__(self, db_addr, db_port, db_name, db_user, db_pwd)
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_service = BillManageService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)

    def get_hotel_zone_type_list(self, org_list,  condition, page, count):
        keys = ['name', 'number', 'remark', 'id']
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill((C('id') == values['id'])
                           & (C('name').like(values['name']))
                           & (C('number').like(values['number']))
                           & (C('remark').like(values['remark']))
                           & (C('organization_id').inner(org_list)))\
               .project({
                   '_id': 0, 'id': 1, 'name': 1, 'remark': 1, 'number': 1
               })
        res = self.page_query(_filter, 'PT_Hotel_Zone_Type', page, count)
        return res

    def update(self, hotel_zone_type):
        res = 'fail'

        def process_func(db):
            nonlocal res
            if 'id' in hotel_zone_type.keys():
                bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
                                                            TypeId.hotelZoneType.value, hotel_zone_type, 'PT_Hotel_Zone_Type')
                if bill_id:
                    res = 'Success'
            else:
                bill_id = self.bill_manage_service.add_bill(OperationType.add.value,
                                                            TypeId.hotelZoneType.value, hotel_zone_type, 'PT_Hotel_Zone_Type')
                if bill_id:
                    res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res

    def del_hotel_zone_type(self, nursing_id_list):
        res = 'Fail'

        def process_func(db):
            nonlocal res
            for id in nursing_id_list:
                data = find_data(db, 'PT_Hotel_Zone_Type', {
                    'id': id, 'bill_status': Status.bill_valid.value})
                if len(data) > 0:
                    self.bill_manage_service.add_bill(OperationType.delete.value,
                                                      TypeId.hotelZoneType.value, data[0], 'PT_Hotel_Zone_Type')
            res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res

    def get_bed_list_no_user(self, org_list, condition, page, count):
        keys = ['id', 'name']
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.match_bill((C('id') == values['id'])
                           & (C('name').like(values['name']))
                           & ((C('residents_id') == None) | (C('residents_id') == ''))
                           & (C('organization_id').inner(org_list))) \
            .inner_join_bill('PT_Hotel_Zone', 'area_id', 'id', 'hotel')\
            .lookup_bill('PT_Bed', 'hotel.id', 'area_id', 'room') \
            .add_fields({'bed_num': self.ao.size('$room'), 'room_name': '$hotel.zone_name',
                         'room_check': self.ao.array_filter('$room', 'up_', (F('$up_.residents_id') != '').f)}) \
            .add_fields({'user_num': self.ao.size('$room_check')})\
            .project({'_id': 0, 'room': 0, 'hotel': 0, 'room_check': 0})
        print(_filter.filter_objects, '《《《《《《《')
        res = self.page_query(_filter, 'PT_Bed', page, count)
        return res

    def get_bed_list(self, org_list,  condition, page=None, count=None):
        '''获取床位列表

        Arguments:
            condition   {dict}      条件
            page        {number}    页码
            count       {number}    条数
        '''
        keys = ['id', 'bed_code', 'name', 'residents', 'area_name']
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        _filter.lookup_bill('PT_User', 'residents_id', 'id', 'user')\
               .lookup_bill('PT_Service_Product', 'service_item_package_id', 'id', 'serviceItemPackage')\
               .lookup_bill('PT_Hotel_Zone', 'area_id', 'id', 'hotelZone')\
               .add_fields({'residents': '$user.name',
                            'service_item_package': '$serviceItemPackage.name',
                            'ared_id': '$hotelZone.id',
                            'area_name': '$hotelZone.zone_name',
                            'create_date': self.ao.date_to_string('$create_date'),
                            'modify_date': self.ao.date_to_string('$modify_date')})\
               .match_bill((C('id') == values['id'])
                           & (C('bed_code').like(values['bed_code']))
                           & (C('name').like(values['name']))
                           & (C('ared_id') == values['area_name'])
                           & (C('residents').like(values['residents']))
                           & (C('organization_id').inner(org_list)))\
               .project({'_id': 0, 'user._id': 0, 'serviceItemPackage._id': 0, 'hotelZone._id': 0})
        res = self.page_query(_filter, 'PT_Bed', page, count)
        return res

    def get_bed_position(self, condition):
        collection_name = 'PT_Bed'
        _filter = MongoBillFilter()

        keys = ['id']
        values = self.get_value(condition, keys)
        _filter\
            .match(
                (C('bill_status') == 'valid')
                & (C('id') == values['id'])
            )\
            .lookup_bill('PT_Hotel_Zone', 'area_id', 'id', 'upper_hotel_zone_tmp')\
            .add_fields({'upper': self.ao.array_filter('$upper_hotel_zone_tmp', 'up_', (F('$up_.bill_status') == 'valid').f)})\
            .graph_lookup('PT_Hotel_Zone', '$upper.upper_hotel_zone_id', 'upper_hotel_zone_id', 'id', 'upper_element')\
            .project({
                '_id': 0,
                'upper._id': 0,
                'upper_hotel_zone_tmp._id': 0,
                'upper_element._id': 0,
            })

        res = self.page_query(_filter, collection_name, None, None)

        return res

    def get_residents_of_bed(self, condition):
        collection_name = 'PT_Bed'
        _filter = MongoBillFilter()

        keys = ['id']
        values = self.get_value(condition, keys)
        _filter\
            .match((C('bill_status') == 'valid')
                   & (C('id') == values['id'])
                   )\
            .lookup_bill('PT_User', 'residents_id', 'id', 'user_tmp')\
            .add_fields({'user': self.ao.array_filter('$user_tmp', 'user_', (F('$user_.bill_status') == 'valid').f)})\
            .project({
                '_id': 0,
                'user._id': 0,
                'user_tmp': 0,
            })

        res = self.page_query(_filter, collection_name, None, None)

        return res

    def update_bed(self, bed):
        '''新增/修改床位'''
        res = 'Fail'
        data_info = get_info({**bed}, self.session)

        def process_func(db):
            nonlocal res
            if 'id' in bed.keys():
                flag = OperationType.update.value
            else:
                flag = OperationType.add.value
                # 如果入住人字段为空，默认给个空字符串
                data_info['residents_id'] = ''
            bill_id = self.bill_manage_service.add_bill(flag,
                                                        TypeId.bed.value, data_info, 'PT_Bed')
            if bill_id:
                res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res

    def delete_bed(self, ids):
        '''删除床位'''
        res = 'Fail'

        def process_func(db):
            nonlocal res
            for business_id in ids:
                data = find_data(db, 'PT_Bed', {
                    'id': business_id, 'bill_status': Status.bill_valid.value})
                if len(data) > 0:
                    self.bill_manage_service.add_bill(OperationType.delete.value,
                                                      TypeId.bed.value, data[0], 'PT_Bed')
            res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res

    def retreat_bed(self, elderId, accommodation_record, accommodation_process):
        ''' 退住
            elderId  长者id
        '''
        # 查询长者绑定的床位
        keys = ['id']
        values = self.get_value({'residents_id': elderId}, keys)
        _filter = MongoBillFilter()
        _filter.lookup_bill('IEC_Check_In', 'residents_id', 'user_id', 'check') \
            .match_bill(C('id') == values['id']) \
            .add_fields({
                'checkIn': self.ao.array_filter('$check', 'up_', ((F('$up_.state') == '居住中').f))
            })\
            .project({'_id': 0, 'check._id': 0, 'checkIn._id': 0})
        res = self.page_query(
            _filter, 'PT_Bed', 1, 1)
        print('数据', res)
        # 解绑床位
        condition = {'residents_id': '', 'id': res['result'][0]['id']}
        self.bill_manage_service.add_bill(
            OperationType.update.value, TypeId.retreat.value, condition, 'PT_Bed')
        # 修改订单状态
        # 获取订单id
        order_id = res['result'][0]['checkIn'][0]['order_id']
        self.bill_manage_service.add_bill(OperationType.update.value, TypeId.retreat.value, {
                                          'id': order_id, 'state': OrderStatus.order_completed}, 'PT_Service_Order')
        # 住宿记录添加离开时间
        days = self.__update_retreat_record({'residents_id': elderId})
        # 生成服务记录
        accommodation_process.get_item_info('住宿', order_id, {'天数': days})
        return res

    def __update_retreat_record(self, condition):
        ''' 住宿记录添加离开时间
            Args:
               {residents_id：长者id} 
        '''
        bill_id = True
        # 获取当前结束时间
        date = get_cur_time()
        condition['checkout_date'] = date
        month_date = get_first_last_day_month(date.year, date.month)
        condition['checkin_date'] = get_string_to_date(month_date[0])
        # 查询本月是否存在住宿记录
        _filter = MongoBillFilter()
        _filter.match_bill((C('residents_id') == condition['residents_id']) & (C('checkin_date') >= condition['checkin_date'])) \
            .sort({'checkin_date': -1})\
            .project({'_id': 0})
        res = self.query(
            _filter, 'PT_Accommodation_Record')
        if len(res):
            if not res[0]['checkout_date']:
                condition['id'] = res[0]['id']
                condition['checkin_date'] = res[0]['checkin_date']
                bill_id = self.bill_manage_service.add_bill(OperationType.update.value,
                                                            TypeId.retreat.value, condition, 'PT_Accommodation_Record')
        else:
            condition = get_info(condition, self.session)
            bill_id = self.bill_manage_service.add_bill(OperationType.add.value,
                                                        TypeId.retreat.value, condition, 'PT_Accommodation_Record')
        days = (condition['checkout_date'] - condition['checkin_date']).days
        return days
